import type { BoardIndex, BoardState, ChessPiece, DifficultyLevel } from '../types'

export function useAI() {
  function getAvailableMoves(board: BoardState): BoardIndex[] {
    return board
      .map((cell, idx) => (cell === null ? idx : null))
      .filter((v): v is BoardIndex => v !== null)
  }

  function checkWinner(board: BoardState, piece: ChessPiece): boolean {
    const winPatterns: BoardIndex[][] = [
      [0, 1, 2],
      [3, 4, 5],
      [6, 7, 8],
      [0, 3, 6],
      [1, 4, 7],
      [2, 5, 8],
      [0, 4, 8],
      [2, 4, 6],
    ]
    return winPatterns.some(pattern =>
      pattern.every(idx => board[idx] === piece),
    )
  }

  // 简单难度：随机落子
  function easyMove(board: BoardState): BoardIndex | null {
    const moves = getAvailableMoves(board)
    if (moves.length === 0)
      return null
    const randIdx = Math.floor(Math.random() * moves.length)
    return moves[randIdx]
  }

  // 中等难度：先找能赢的点，找不到随机
  function mediumMove(board: BoardState, aiPiece: ChessPiece, playerPiece: ChessPiece): BoardIndex | null {
    const moves = getAvailableMoves(board)
    if (moves.length === 0)
      return null

    // 先找能赢的位置
    for (const move of moves) {
      const boardCopy = [...board]
      boardCopy[move] = aiPiece
      if (checkWinner(boardCopy, aiPiece))
        return move
    }
    // 再找能阻挡玩家赢的位置
    for (const move of moves) {
      const boardCopy = [...board]
      boardCopy[move] = playerPiece
      if (checkWinner(boardCopy, playerPiece))
        return move
    }

    // 否则随机
    const randIdx = Math.floor(Math.random() * moves.length)
    return moves[randIdx]
  }

  // 困难难度：minimax算法
  function hardMove(board: BoardState, aiPiece: ChessPiece, playerPiece: ChessPiece): BoardIndex | null {
    const moves = getAvailableMoves(board)
    if (moves.length === 0)
      return null

    function minimax(board: BoardState, currentPiece: ChessPiece, depth: number): { score: number, move?: BoardIndex } {
      if (checkWinner(board, aiPiece))
        return { score: 10 - depth }
      if (checkWinner(board, playerPiece))
        return { score: depth - 10 }
      if (getAvailableMoves(board).length === 0)
        return { score: 0 }

      const moves = getAvailableMoves(board)
      let bestMove: BoardIndex | undefined
      let bestScore = currentPiece === aiPiece ? -Infinity : Infinity

      for (const move of moves) {
        board[move] = currentPiece
        const result = minimax(board, currentPiece === aiPiece ? playerPiece : aiPiece, depth + 1)
        board[move] = null

        if (currentPiece === aiPiece) {
          if (result.score > bestScore) {
            bestScore = result.score
            bestMove = move
          }
        }
        else {
          if (result.score < bestScore) {
            bestScore = result.score
            bestMove = move
          }
        }
      }
      return { score: bestScore, move: bestMove }
    }

    return minimax(board, aiPiece, 0).move ?? null
  }

  function getMove(difficulty: DifficultyLevel, board: BoardState, aiPiece: ChessPiece, playerPiece: ChessPiece): BoardIndex | null {
    switch (difficulty) {
      case 'easy':
        return easyMove(board)
      case 'medium':
        return mediumMove(board, aiPiece, playerPiece)
      case 'hard':
        return hardMove(board, aiPiece, playerPiece)
    }
  }

  return { getMove }
}
